package com.softcits.hw.aop.aspect;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class CalculatorLoggingAspect {
    
    @Pointcut("execution(* *.add(..)) || execution(* *.minus(..) )")
    public void loggingPointCuts() {
        
    }

    
    @Before("loggingPointCuts()")
    public void logBefore(JoinPoint jp) {
        System.out.println("The method add Before...");
    }
    
    
    @After("loggingPointCuts()")
    public void logAfter(JoinPoint jp) {
        jp.getSignature().getName();
        System.out.println("The method add After...");
    }
    
    @AfterReturning(value = "execution(* *.add(..))", returning="ret")
    public void logAfterReturning(JoinPoint jp, Object ret) {
        System.out.println("After Returning: return value is " + ret);
    }
    
    @AfterThrowing(value = "execution(* *.divide(..))", throwing="re")
    public void logAfterThrowing(JoinPoint jp, RuntimeException re) {
        System.out.println("After Throwing: exception is " + re.getMessage());
    }
    
    @Around("@annotation(com.softcits.hw.aop.aspect.AdminRole)")
    public Double roleAround(ProceedingJoinPoint pjp) {
        System.out.println("admin role before");
        String args = Arrays.toString(pjp.getArgs());
        System.out.println("args = " + args);
        Object ret = null;
        try {
           ret = pjp.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        
        System.out.println("admin role end");
        return (Double) ret;
    }
}
